import { _decorator, Component, Node, Button, Label } from 'cc';
import { BasePanel } from '../../../../scripts/libs/ui/BasePanel';
import { BindButton } from '../../../../scripts/libs/rxjs/cc3/BindButton';
import { ReactiveProperty } from '../../../../scripts/libs/rxjs/cc3/ReactiveProperty';
import { StageView } from '../GamePanel/2d/StageView';
import { udm } from '../../../../scripts/managers/UserDataManager';
import { lm } from '../../LobbyManager';
import { FlowStatus } from '../../Enums';
import { gm } from '../../../../scripts/managers/GameManager';
import { BuyHeartPanel } from '../BuyHeartPanel/BuyHeartPanel';
import { thinking_sdk_m } from '../../../../scripts/managers/SDK/ThinkingCocosSDKManager';
import { ShopPanel } from '../ShopPanel/ShopPanel';
import { DevConfig } from '../../../../scripts/managers/DevConfig';
import { adsm } from '../../../../scripts/managers/AdsManager';
import { Observable, of, Subscription, merge, concat, forkJoin } from 'rxjs';
import { am } from '../../../../scripts/managers/AudioManager';
import { BundleItem } from '../LobbyPanel/ShopPage/BundleItem';
import { StringTools } from '../../../../scripts/libs/utils/StringTools';
import { MergeASAP } from '../../../../scripts/libs/rxjs/cc3/Merge';
import { TweenToStart } from '../../../../scripts/libs/rxjs/cc3/TweenStart';
import { nullifySubscription } from '../../../../scripts/libs/rxjs/utils';
import { ProvideInfo } from '../../../../scripts/managers/SDK/IapSDKManager';
import { GotAwardPanel } from '../GotAwardPanel/GotAwardPanel';
import { v3 } from 'cc';
import { instantFunc } from '../../../../scripts/libs/rxjs/cc3/CommonObservable';
import { UIOpacity } from 'cc';
import { view } from 'cc';
import { linear } from '../../../../scripts/libs/utils/math';
const { ccclass, property } = _decorator;

@ccclass('GameLosePanel')
export class GameLosePanel extends BasePanel {

    stageView: StageView = null;

    @property(Node)
    mainNode: Node = null;

    @property(Node)
    boardNode: Node = null;

    @property(Button)
    closeButton: Button = null;

    @property(Button)
    retryButton: Button = null;

    @property(Button)
    adsReviveButton: Button = null;

    @property(Button)
    reviveButton: Button = null;

    @property(Label)
    reviveButtonLabel: Label = null;

    closeOnce = ReactiveProperty.Create(true);

    needCoin = 0;

    @property([BundleItem])
    bundleItems: BundleItem[] = [];

    @property(Label)
    coinCountLabel: Label = null;

    @property(Node)
    pageViewNode: Node = null;

    coinValue = ReactiveProperty.Create(0);

    @property([Node])
    heartNodes: Node[] = [];

    willBind(): void {
        gm.currentAdsType.value = 'AdLoseRevive';
        gm.currentAdsOpenUI.value = 'GameLose';
        gm.currentInterstitialAdsType.value = 'AdLose';
        this.needCoin = DevConfig.COIN_LOSE_CONTINUE_NEED * (gm.continueCount.value + 1);
        this.reviveButtonLabel.string = `${this.needCoin}`;
        this.adaptive();
    }

    useObserves() {
        return [
            BindButton(this.closeButton).subscribe(this.closeButtonClicked.bind(this)),
            BindButton(this.retryButton).subscribe(this.retryButtonClicked.bind(this)),
            BindButton(this.adsReviveButton).subscribe(this.adsReviveButtonClicked.bind(this)),
            BindButton(this.reviveButton).subscribe(this.reviveButtonClicked.bind(this)),
            this.closeOnce.subscribePairWise(this.closeOnceChanged.bind(this)),
            this.coinValue.subscribe(this.refreshCoin.bind(this)),
            MergeASAP(udm.coin, gm.coinAnimatingFlags, udm.temp_coin_diff).subscribe(this.refreshCoinTarget.bind(this)),
            merge(
                this.bundleItems[0].iapButtonItem.beforeProvideCommand._subject,
                this.bundleItems[1].iapButtonItem.beforeProvideCommand._subject,
                this.bundleItems[2].iapButtonItem.beforeProvideCommand._subject
            ).subscribe(this.iapBeforeProvideHandler.bind(this)),
            merge(
                this.bundleItems[0].iapButtonItem.successCommand._subject,
                this.bundleItems[1].iapButtonItem.successCommand._subject,
                this.bundleItems[2].iapButtonItem.successCommand._subject
            ).subscribe(this.iapSuccessHandler.bind(this)),
            MergeASAP(udm.heart, udm.infHeartTill).subscribe(this.refresh.bind(this)),
        ];
    }

    onLoadView(): void {
        this.bundleItems[0].data.value = DevConfig.iap.bundle_0;
        this.bundleItems[1].data.value = DevConfig.iap.bundle_1;
        this.bundleItems[2].data.value = DevConfig.iap.bundle_3;
        this.closeOnce.value = true;

        thinking_sdk_m.requestTrack('Ads_Show', {
            AdsType: 'AdLoseRevive',
            OpenUI: 'GameLosePanel',
            IsNew: udm.isNew.value
        });
    }

    onDestroyView(): void {
        nullifySubscription.call(this, '_sub_coin_value_tween');
    }

    willOpen(): Observable<string> {
        am.playSfx({ clipName: `ab_lobby/Audio/sfx/LevelFailed` });
        return of(null);
    }

    adaptive() {
        let height = view.getVisibleSize().height;
        let scale = linear(1650, 2400, .7, 1, height);
        this.boardNode.setScale(scale, scale, scale);
    }

    closeOnceChanged(pair) {
        if (this.closeOnce.value) {
            if (!pair[0] && pair[1]) { // 需要动画
                concat(
                    forkJoin([
                        TweenToStart(this.mainNode, .2, { scale: v3(.5, .5, .5) }, { easing: 'sineOut' }),
                        TweenToStart(this.mainNode.getComponent(UIOpacity), .2, { opacity: 0 }, { easing: 'sineOut' }),
                    ]),
                    instantFunc(() => {
                        this.adsReviveButton.node.active = false;
                        this.retryButton.node.active = true;
                    }),
                    forkJoin([
                        TweenToStart(this.mainNode, .2, { scale: v3(1, 1, 1) }, { easing: 'sineIn' }),
                        TweenToStart(this.mainNode.getComponent(UIOpacity), .2, { opacity: 255 }, { easing: 'sineIn' }),
                    ])
                ).subscribe().addTo(this.node);
            } else {
                this.adsReviveButton.node.active = false;
                this.retryButton.node.active = true;
            }
        } else {
            this.adsReviveButton.node.active = true;
            this.retryButton.node.active = false;
        }
    }

    closeButtonClicked() {
        if (this.closeOnce.value) {

            adsm.tryShowInterstitialAds(gm.stageInfo.value, 'AdFail'); // 展示插屏广告已经全部封装

            GameLosePanel.CloseProcess(null, 'exit');
            udm.gameLose(this.stageView.stageInfo, 'lose_quit');
            lm.flowStatus.value = FlowStatus.Lobby;
        } else {
            this.closeOnce.value = true;
        }
    }

    retryButtonClicked() {
        let heartCount = udm.getHeartCount();
        if (udm.getRemainMsToOverInfHeart() > 0 || heartCount >= 2) { // 如果有两颗心，那么扣掉一颗还剩一颗，可以直接重开游戏
            udm.gameLose(this.stageView.stageInfo, 'lose_restart');
            gm.loadGameCommand.execute();
            adsm.tryShowInterstitialAds(gm.stageInfo.value, 'AdFail'); // 展示插屏广告已经全部封装
            GameLosePanel.CloseProcess(null, 'again');
        } else if (heartCount == 1) { // 如果只有一颗心，那么本局是失败的，扣过之后没有心了不能重新开始，所有要求先补充心
            BuyHeartPanel.StartProcess().subscribe(_ => {
                if (_ == 'continue') {
                    udm.gameLose(this.stageView.stageInfo, 'lose_restart');
                    gm.loadGameCommand.execute();
                    adsm.tryShowInterstitialAds(gm.stageInfo.value, 'AdFail'); // 展示插屏广告已经全部封装
                    GameLosePanel.CloseProcess(null, 'again');
                }
            });
        } else {
            thinking_sdk_m.requestTrack('Shoping_Open', {
                OpenType: 'NoEnergy',
                OpenWay: 'Result',
                IsNew: udm.isNew.value,
                Level_ID: udm.stageNum.value,
            });
            ShopPanel.StartProcess().subscribe();
        }
    }

    adsReviveButtonClicked() {
        gm.currentAdsType.value = 'AdLoseRevive';
        gm.currentAdsOpenUI.value = 'GameLose';
        thinking_sdk_m.requestTrack('Ads_Click', {
            AdsType: gm.currentAdsType.value,
            OpenUI: gm.currentAdsOpenUI.value,
            IsNew: udm.isNew.value
        });
        adsm.showRewardAds('stage_lose_revive').subscribe(_ => {
            if (_ == 'success') {
                thinking_sdk_m.requestTrack('Ads_Return', {
                    AdsType: gm.currentAdsType.value,
                    OpenUI: gm.currentAdsOpenUI.value,
                    IsNew: udm.isNew.value
                });
                gm.reviveTimes.value++;
                udm.gameRevive(this.stageView.stageInfo, 'Ad');
                udm.save();
                GameLosePanel.CloseProcess(null, 'revive');
            }
        });
    }

    reviveButtonClicked() {
        if (!this.stageView.waitingPlacehasAnimating() && !this.stageView.queueHasAnimating()) {
            if (udm.coin.value >= this.needCoin) {
                thinking_sdk_m.requestTrack('Coins_Use', {
                    CoinNum: this.needCoin,
                    Type: 'Revive',
                    IsNew: udm.isNew.value,
                    Level_ID: udm.stageNum.value,
                });
                gm.reviveTimes.value++;
                udm.gameRevive(this.stageView.stageInfo, 'Gold');
                udm.coin.value -= this.needCoin;
                udm.save();
                gm.coinUse.value += this.needCoin;
                GameLosePanel.CloseProcess(null, 'revive');
            } else {
                thinking_sdk_m.requestTrack('Shoping_Open', {
                    OpenType: 'NoGold',
                    OpenWay: 'Result',
                    IsNew: udm.isNew.value,
                    Level_ID: udm.stageNum.value,
                });
                ShopPanel.StartProcess().subscribe();
            }
        } else {
            lm.frontTipShow('Please wait...');
        }
    }

    refreshCoin() {
        this.coinCountLabel.string = StringTools.toKDotString(Math.floor(this.coinValue.value));
    }

    _sub_coin_value_tween: Subscription = null;
    refreshCoinTarget() {
        if (udm.temp_coin_diff.value != null) {
            this._sub_coin_value_tween = TweenToStart(this.coinValue, .4, { value: this.coinValue.value + udm.temp_coin_diff.value }).subscribe();
            return;
        }
        if (gm.coinAnimatingFlags.size > 0) return;
        nullifySubscription.call(this, '_sub_coin_value_tween');
        this._sub_coin_value_tween = TweenToStart(this.coinValue, .4, { value: udm.coin.value }).subscribe();
    }

    iapBeforeProvideHandler(provide: ProvideInfo) {
        gm.coinAnimatingFlags.add('iap_coin');
    }

    iapSuccessHandler(provide: ProvideInfo) {
        this.log('@iapSuccessHandler', provide);
        this.pageViewNode.active = false;
        GotAwardPanel.StartProcess((panel: GotAwardPanel) => {
            panel.data.value = provide;
        }).subscribe(_ => {
            if (_ == 'claim') {
                gm.coinAnimatingFlags.delete('iap_coin');
            }
        });
    }

    refresh() {
        let remainMsInfHeart = udm.getRemainMsToOverInfHeart();
        if (remainMsInfHeart > 0) { // 在无限体力状态下
            this.heartNodes.forEach(_ => _.active = false);
        } else {
            this.heartNodes.forEach(_ => _.active = true);
        }
    }

}

